using System;
using System.Runtime.InteropServices;

namespace WindowsAPI.PE
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct CoffHeader
    {
        public IMAGE_FILE_MACHINE Machine;

        public ushort NumberOfSection;

        public uint TimeDateStamp;

        public uint PointerToSymbolTable;

        public uint NumberOfSymbols;

        public ushort SizeOfOptionalHeader;

        public Characteristic Characteristics;

        public CoffHeader(byte[] data, bool IsUnsafe = false)
        {
            // the isUnsafe parameter is not a good style
            // normally we choose one way
            if(IsUnsafe)
            {
                unsafe
                {
                    fixed(byte* packet = &data[0])
                    {
                        // structs has the ability to assign itself in the c'tor
                        this = *(CoffHeader*)packet;
                        return;
                    }
                }
            }

            var coffPtr = IntPtr.Zero;
            try
            {
                var size = Marshal.SizeOf(typeof(CoffHeader));
                coffPtr = Marshal.AllocHGlobal(size);
                Marshal.Copy(data, 0, coffPtr, size);
                this = (CoffHeader)Marshal.PtrToStructure(coffPtr, typeof(CoffHeader));
            }
            finally
            {
                Marshal.FreeHGlobal(coffPtr);
            }
        }

        public override string ToString()
        {
            var time = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(TimeDateStamp);
            return string.Format(" - Machine: {0}\r\n" +
                                 " - NumberOfSection: {1}\r\n" +
                                 " - TimeDateStamp: {2}\r\n" +
                                 " - PointerToSymbolTable: {3}\r\n" +
                                 " - NumberOfSymbols: {4}\r\n" +
                                 " - SizeOfOptionalHeader: {5}\r\n" +
                                 " - Characteristics: {6}",
                                      Machine,
                                      NumberOfSection,
                                      time,
                                      PointerToSymbolTable,
                                      NumberOfSymbols,
                                      SizeOfOptionalHeader,
                                      Characteristics);
        }
    }
}